import { defineStore } from 'pinia'
import { readText } from '@tauri-apps/plugin-clipboard-manager'
import Database from '@tauri-apps/plugin-sql'
import { onBeforeUnmount } from 'vue'

interface ClipboardItem {
  id: number
  content: string
  timestamp: number
  favorite: boolean
}

let dbInstance: any = null
let dbInitPromise: Promise<any> | null = null

// 清理函数
async function cleanup() {
  if (dbInstance) {
    try {
      await dbInstance.close()
      dbInstance = null
      dbInitPromise = null
    } catch (error) {
      console.error('Failed to close database:', error)
    }
  }
}

export const useClipboardStore = defineStore('clipboard', {
  state: () => ({
    items: [] as ClipboardItem[],
  }),

  actions: {
    async initDatabase() {
      try {
        // 如果已经有初始化过程在进行，等待它完成
        if (dbInitPromise) {
          return await dbInitPromise
        }

        // 如果数据库已经初始化，直接返回
        if (dbInstance) {
          return dbInstance
        }

        // 创建新的初始化Promise
        dbInitPromise = (async () => {
          dbInstance = await Database.load('sqlite:clipboard.db')
          
          // 创建表（如果不存在）
          await dbInstance.execute(`
            CREATE TABLE IF NOT EXISTS clipboard_items (
              id INTEGER PRIMARY KEY AUTOINCREMENT,
              content TEXT NOT NULL,
              timestamp INTEGER NOT NULL,
              favorite INTEGER NOT NULL DEFAULT 0
            )
          `)

          // 启用 WAL 模式以提高性能和并发性
          await dbInstance.execute('PRAGMA journal_mode=WAL')
          // 启用外键约束
          await dbInstance.execute('PRAGMA foreign_keys=ON')
          // 设置同步模式
          await dbInstance.execute('PRAGMA synchronous=NORMAL')
          // 设置内存缓存大小
          await dbInstance.execute('PRAGMA cache_size=2000')
          // 设置页面缓存
          await dbInstance.execute('PRAGMA page_size=4096')
          
          return dbInstance
        })()

        // 注册清理函数
        onBeforeUnmount(cleanup)

        return await dbInitPromise
      } catch (error) {
        console.error('Failed to initialize database:', error)
        dbInitPromise = null
        throw error
      }
    },

    async loadClipboardItems() {
      const db = await this.initDatabase()
      try {
        const result = await db.select(
          'SELECT id, content, timestamp, favorite FROM clipboard_items ORDER BY timestamp DESC'
        ) as Array<{id: number, content: string, timestamp: number, favorite: number}>
        
        this.items = result.map(item => ({
          ...item,
          favorite: Boolean(item.favorite)
        }))
      } catch (error) {
        console.error('Failed to load clipboard items:', error)
        this.items = []
      }
    },

    async handleClipboardChange() {
      const db = await this.initDatabase()
      try {
        const content = await readText()
        if (!content || content.trim() === '' || this.items.some(item => item.content === content)) {
          return
        }

        const timestamp = Date.now()
        
        await db.execute(
          'INSERT INTO clipboard_items (content, timestamp, favorite) VALUES ($1, $2, $3)',
          [content, timestamp, 0]
        )
        
        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to handle clipboard change:', error)
      }
    },

    async addItem(content: string) {
      const db = await this.initDatabase()
      try {
        if (!content || content.trim() === '') return

        const timestamp = Date.now()
        await db.execute(
          'INSERT INTO clipboard_items (content, timestamp, favorite) VALUES ($1, $2, $3)',
          [content, timestamp, 0]
        )
        
        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to add item:', error)
      }
    },

    async deleteItem(id: number) {
      const db = await this.initDatabase()
      try {
        await db.execute('DELETE FROM clipboard_items WHERE id = $1', [id])
        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to delete item:', error)
      }
    },

    async updateItem(item: Partial<ClipboardItem> & { id: number }) {
      const db = await this.initDatabase()
      try {
        // 首先从数据库获取当前项目
        const [currentItem] = await db.select(
          'SELECT id, content, timestamp, favorite FROM clipboard_items WHERE id = $1',
          [item.id]
        ) as Array<{id: number, content: string, timestamp: number, favorite: number}>

        if (!currentItem) return

        // 合并更新
        const updatedItem = {
          id: currentItem.id,
          content: item.content ?? currentItem.content,
          timestamp: item.timestamp ?? currentItem.timestamp,
          favorite: typeof item.favorite === 'boolean' ? item.favorite : Boolean(currentItem.favorite)
        }
        
        // 更新数据库
        await db.execute(
          'UPDATE clipboard_items SET content = $1, timestamp = $2, favorite = $3 WHERE id = $4',
          [updatedItem.content, updatedItem.timestamp, updatedItem.favorite ? 1 : 0, updatedItem.id]
        )

        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to update item:', error)
      }
    },

    async clearAll() {
      const db = await this.initDatabase()
      try {
        await db.execute('DELETE FROM clipboard_items WHERE favorite = 0')
        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to clear all:', error)
      }
    },

    async clearFavorites() {
      const db = await this.initDatabase()
      try {
        await db.execute('DELETE FROM clipboard_items WHERE favorite = 1')
        await this.loadClipboardItems()
      } catch (error) {
        console.error('Failed to clear favorites:', error)
      }
    },

    async saveToDatabase() {
      const db = await this.initDatabase()
      try {
        await db.execute('BEGIN TRANSACTION')
        
        try {
          await db.execute('DELETE FROM clipboard_items')
          
          // 使用单个 SQL 语句批量插入
          if (this.items.length > 0) {
            const values = this.items.map(item => 
              `(${JSON.stringify(item.content)}, ${item.timestamp}, ${item.favorite ? 1 : 0})`
            ).join(',')
            
            await db.execute(`
              INSERT INTO clipboard_items (content, timestamp, favorite) 
              VALUES ${values}
            `)
          }
          
          await db.execute('COMMIT')
          await this.loadClipboardItems()
        } catch (error) {
          await db.execute('ROLLBACK')
          throw error
        }
      } catch (error) {
        console.error('Failed to save to database:', error)
      }
    }
  }
}) 